package com.hk.userservice.service.es.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hk.model.LoginLog;
import com.hk.userservice.model.es.EsLoginLog;
import com.hk.userservice.service.LoginLogService;
import com.hk.userservice.service.es.EsLoginLogService;
import com.hk.userservice.utils.EsUtil;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.rest.RestStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zhe
 * @Create 2021/8/1/8:07
 * @State Es 登录日志服务类
 */
@Slf4j
@Service
public class EsLoginLogServiceImpl implements EsLoginLogService {

    @Autowired
    private EsUtil esUtil;

    @Autowired
    private LoginLogService loginLogService;


    /**
     * 搜索条件 姓名、邮箱、IP、状态、
     * @param page
     * @param limit
     * @param loginLog
     * @return
     */
    @Override
    public Map<String, Object> searchDocument(Integer page, Integer limit, EsLoginLog loginLog) throws IOException {
//        查询条件
        Map<String,Object> map = new HashMap<>();
        map.put("loginName",loginLog.getLoginName());
        map.put("email",loginLog.getEmail());
        map.put("loginIp",loginLog.getLoginIp());
        map.put("state",loginLog.getState());
//        判断索引库是否需存在，不存在创建
        boolean exists = esUtil.isIndexExists(EsUtil.ES_INDEX);
//        索引库存在，开始搜索
        if (exists) {
            Map<String, Object> document = esUtil.searchDocument(EsUtil.ES_INDEX, 10l, page, limit, map);
            map = resultMap(map, document);
            return map;
        }
        boolean index = esUtil.createIndex(EsUtil.ES_INDEX, EsUtil.ES_SHARDS, EsUtil.ES_REPLICAS);
//        1、创建成功
        if (index) {
            log.error(EsUtil.ES_INDEX+"索引库创建成功！");
//           2、批量插入数据 ,读取mysql数据
            int count = loginLogService.count(-1, -1, new LoginLog());
            List<LoginLog> loginLogList = loginLogService.findAll(1,count,new LoginLog());
//            3、批量插入
            List<IndexRequest> list = new ArrayList<>(100);
            for (LoginLog log : loginLogList) {
                IndexRequest indexRequest = new IndexRequest(EsUtil.ES_INDEX);
//            _id
                indexRequest.id(log.getId().toString());
                indexRequest.source(JSON.toJSONString(log), XContentType.JSON);
                list.add(indexRequest);
            }
            log.error("开始批量插入...");
            boolean b = esUtil.bulkCreateDocument(10l, list);
//            批量插入成功 true 失败 false成功
            if (!b) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                log.error("批量插入成功.....");
//                开始搜索
                Map<String, Object> document = esUtil.searchDocument(EsUtil.ES_INDEX, 10l, page, limit, map);
                map = resultMap(map, document);
                return map;
            }
        }
        return null;
    }

    @Override
    public boolean createDocument(String index, Object o, String _id, long requestTime) throws IOException {
        RestStatus document = esUtil.createDocument(index, o, _id, requestTime);
        if (document.toString() == "CREATED") {
            log.error("Es登录日志保存成功！");
            return true;
        }
        return false;
    }

    @Override
    public EsLoginLog getDocumentInfo(String index, String _id) throws IOException {
        String documentInfo = esUtil.getDocumentInfo(index, _id);
        EsLoginLog esLoginLog = JSONObject.parseObject(documentInfo, EsLoginLog.class);
        return esLoginLog;
    }

    @Override
    public boolean updateDocumentInfo(String index, String _id, Object o, long requestTime) throws IOException {
        RestStatus restStatus = esUtil.updateDocumentInfo(index, _id, o, requestTime);
        if (restStatus.toString() == "OK") {
            log.error("Es的登录日志修改成功！");
            return true;
        }
        return false;
    }

    @Transactional
    @Override
    public boolean deleteDocumentInfo(String index, String _id, long requestTime) throws IOException {
        RestStatus restStatus = esUtil.deleteDocumentInfo(index, _id, requestTime);
        if (restStatus.toString() == "OK") {
            log.error("Es的登录日志删除成功！");
//            Mysql删除登录日志
            loginLogService.delete(Integer.parseInt(_id));
            return true;
        }
        return false;
    }

    /**
     * 封装返回结果
     * @param map 搜索条件（避免重复创建对象）
     * @param document 搜索请求获取的结果
     * @return 封装后的map结果
     */
    public Map<String,Object> resultMap(Map<String,Object> map,Map<String, Object> document) {
        // 清空搜索条件
        map.clear();
        //            总条数
        long total = (long) document.get("total");
        List<EsLoginLog> loginLogList = documentObject(document);
        map.put("total",total);
        map.put("list",loginLogList);
        return map;
    }

    /**
     * 返回值转化为对象
     * @param document 获取的结果
     * @return 返回的对象集合
     */
    public List<EsLoginLog> documentObject(Map<String, Object> document) {
        //        存放转化后的搜索结果
        List<EsLoginLog> loginLogList = new ArrayList<>(100);
        List<Map<String,Object>> list = (List<Map<String, Object>>) document.get("list");
        for (Map<String, Object> objectMap : list) {
            Integer id = (Integer) objectMap.get("id");
            Integer loginId = (Integer) objectMap.get("loginId");
            String loginName = (String) objectMap.get("loginName");
            String email = (String) objectMap.get("email");
            String loginIp = (String) objectMap.get("loginIp");
            String gmtCreate = (String) objectMap.get("gmtCreate");
            String gmtModified = (String) objectMap.get("gmtModified");
            Integer state = (Integer) objectMap.get("state");
            EsLoginLog loginLog1 = EsLoginLog.builder()
                    .id(id)
                    .loginId(loginId)
                    .loginName(loginName)
                    .email(email)
                    .loginIp(loginIp)
                    .gmtCreate(gmtCreate)
                    .gmtModified(gmtModified)
                    .state(state).build();
            loginLogList.add(loginLog1);
        }
        return loginLogList;
    }

    @Override
    public boolean deleteIndex(String index, long requestTime) throws IOException {
        boolean b = esUtil.deleteIndex(index, requestTime);
        return b;
    }
}
